﻿using _2._18._2015_MoviesInClass.Data.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.Migrations;
using System.Data.Entity.Validation;

namespace _2._18._2015_MoviesInClass.Data
{
    public static class Seeder
    {
        public static void Seed(MoviesDbContext context)
        {
            UserStore<User> userStore = new UserStore<User>(context);
            UserManager<User> userManager = new UserManager<User>(userStore);

            RoleStore<Role> roleStore = new RoleStore<Role>(context);
            RoleManager<Role> roleManager = new RoleManager<Role>(roleStore);

            try
            {
                #region Seed Roles

                if (!roleManager.RoleExists("Admin"))
                    roleManager.Create(new Role { Name = "Admin" });

                if (!roleManager.RoleExists("General"))
                    roleManager.Create(new Role { Name = "General" });

                User nick = userManager.FindByEmail("nick@codercamps.com");
                User arun = userManager.FindByEmail("arun@codercamps.com");

                #endregion

                #region Seed Users

                if (nick == null)
                {
                    nick = new User
                    {
                        Email = "nick@codercamps.com",
                        UserName = "nick@codercamps.com"
                    };

                    userManager.Create(nick, "123456");

                    nick = userManager.FindByEmail("nick@codercamps.com");
                }

                if (!userManager.IsInRole(nick.Id, "Admin"))
                    userManager.AddToRole(nick.Id, "Admin");

                if (arun == null)
                {
                    arun = new User
                    {
                        Email = "arun@codercamps.com",
                        UserName = "arun@codercamps.com"
                    };

                    userManager.Create(arun, "123456");

                    arun = userManager.FindByEmail("arun@codercamps.com");
                }

                if (!userManager.IsInRole(arun.Id, "General"))
                    userManager.AddToRole(arun.Id, "General");

                #endregion

                #region Seed Movies

                Movie starWars = new Movie
                {
                    Title = "Star Wars",
                    Rating = 5,
                    UserId = nick.Id,
                    PosterUrl = "http://a.tgcdn.net/images/products/additional/large/e948_classic_star_wars_movie_posters3.jpg",
                    CreatedById = nick.Id,
                    UpdatedById = nick.Id,
                    DateCreated = DateTime.Now,
                    DateUpdated = DateTime.Now
                };

                Movie goonies = new Movie
                {
                    Title = "Goonies",
                    Rating = 10,
                    UserId = arun.Id,
                    PosterUrl = "http://static1.squarespace.com/static/52875bf0e4b0b40559bc2145/53bc4abfe4b044938a07ce7c/53bc4b10e4b0f9fe5b57c927/1404848915289/the-goonies-poster-02-1985.png",
                    CreatedById = nick.Id,
                    UpdatedById = nick.Id,
                    DateCreated = DateTime.Now,
                    DateUpdated = DateTime.Now
                };

                context.Movies.AddOrUpdate(m => m.Title,
                    starWars,
                    goonies);

                context.SaveChanges();

                #endregion

                #region Seed Actors

                Actor billy = new Actor
                {
                    FirstName = "Billy",
                    LastName = "Bob",
                    CreatedById = nick.Id,
                    DateCreated = DateTime.Now,
                    UpdatedById = nick.Id,
                    DateUpdated = DateTime.Now
                };

                Actor joe = new Actor
                {
                    FirstName = "Joe",
                    LastName = "Johnson",
                    CreatedById = arun.Id,
                    DateCreated = DateTime.Now,
                    UpdatedById = arun.Id,
                    DateUpdated = DateTime.Now
                };

                context.Actors.AddOrUpdate(a => new { a.FirstName, a.LastName },
                    billy,
                    joe);

                context.SaveChanges();

                #endregion

                #region Seed Movie Actors

                if (!context.MovieActors.Any())
                {
                    context.MovieActors.Add(new MovieActor { ActorId = billy.ActorId, MovieId = goonies.MovieId });
                    context.MovieActors.Add(new MovieActor { ActorId = joe.ActorId, MovieId = goonies.MovieId });
                    context.MovieActors.Add(new MovieActor { ActorId = joe.ActorId, MovieId = starWars.MovieId });
                }

                #endregion

                context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                //Yes, this is disturbing but this is how I can enumerate through the 'real' validation error messages
                //and create one giant string of all the errors and the entity that through the error so I can
                //see them in the console when the seeder fails (sigh)
                var errors = string.Join(" | ", ex.EntityValidationErrors
                    .ToList()
                    .Select(ev => 
                        string.Join(": ", new string[] { ev.Entry.Entity.ToString(), 
                            string.Join(", ", ev.ValidationErrors.Select(ve => 
                                string.Join(": ", new string[] { ve.PropertyName, ve.ErrorMessage })))})));

                throw new Exception(errors);
            }
        }
    }
}
